<template>
  <div class="canvas-container" ref="container">
    <!--    <Cube />-->
    <!-- 缩放控制按钮 -->
    <div class="zoom-controls">
      <el-button
          circle
          size="mini"
          @click="handleZoom(-1)"
          title="缩小"
      >
        <i class="el-icon-zoom-in"></i>
      </el-button>
      <el-button
          circle
          size="mini"
          @click="handleZoom(1)"
          title="放大"
      >
        <i class="el-icon-zoom-out"></i>
      </el-button>
    </div>
  </div>
</template>

<script type="module">
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
// import Cube from '@/components/Cube.vue'
import {Mesh, MeshStandardMaterial} from "three";
import {OBJLoader} from "three/addons/loaders/OBJLoader";
import {mapState} from "vuex";

export default {
  name: 'Canvas3D',
  props: {
    canvasTexture: {
      type: Object,
      default: null
    },
    hasSelection: {
      type: Boolean,
      default: false
    },
    disableControls: {
      type: Boolean,
      default: false
    },
    isScreenshotting: {
      type: Boolean,
      default: false
    }
  },
  // components: {
  //   Cube
  // },
  computed: {
    ...mapState({
      selectedProductType: state => state.designs.selectedProductType,
      selectedModel: state => {
        const models = state.models.models;
        return models.find(m => m.id === state.models.selectedModelId);
      }
    }),
  },
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      controls: null,
      cubeMesh: null,
      model: null,
      zoom: 5,
      defaultCameraPosition: {
        position: new THREE.Vector3(0, 0, 6),
        target: new THREE.Vector3(0, 0, 0)
      }
    };
  },
  mounted() {
    this.initThree();
    this.initMaterial();
    // this.animate();
  },
  beforeDestroy() {
    this.cleanup();
  },
  methods: {
    onInteract() {
      this.$emit('interact');
    },
    initThree() {
      // 初始化场景
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color(0xf0f0f0);

      // 初始化相机
      this.camera = new THREE.PerspectiveCamera(
          45,
          this.$refs.container.clientWidth / this.$refs.container.clientHeight,
          0.1,
          1000
      );
      this.camera.position.copy(this.defaultCameraPosition.position);

      // 初始化渲染器
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        preserveDrawingBuffer: true
      });
      this.renderer.setSize(
          this.$refs.container.clientWidth,
          this.$refs.container.clientHeight
      );
      this.$refs.container.appendChild(this.renderer.domElement);

      // // 添加光源
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
      this.scene.add(ambientLight);

      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.6);
      directionalLight1.position.set(1, 2, 1);
      directionalLight1.castShadow = true;
      this.scene.add(directionalLight1);

      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.3);
      directionalLight2.position.set(-1, 2, -1);
      this.scene.add(directionalLight2);

      // // 添加轨道控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.dampingFactor = 0.05;
      this.controls.makeDefault = false;
      this.controls.enabled = true;
      this.controls.enableRotate = true;
      this.controls.enableZoom = true;
      this.controls.enablePan = true;

      // this.controls.target.set(0, 0, 0); // 确保控制器目标在原点
      // this.controls.update();


      // 调整相机位置
      // this.camera.position.z = 5;
      this.camera.position.set(0, 0, 6);
      this.camera.lookAt(0, 0, 0);
      // this.renderer.render(this.scene, this.camera);

      // 添加事件监听
      this.renderer.domElement.addEventListener('mousedown', this.handleMouseDown);
      window.addEventListener('resize', this.onWindowResize);
    },

    initMaterial() {
      this.material = new MeshStandardMaterial({
        color: 'white',
        roughness: 0.9,
        metalness: 0,
        envMapIntensity: 0.2,
        transparent: true,
        side: 2,
        map: this.canvasTexture || null
      });

      // 3. 创建几何体+材质组合
      const geometry = new THREE.BufferGeometry()
      geometry.center()
      this.cubeMesh = new THREE.Mesh(geometry, this.material)
      console.log('990', this.cubeMesh.position)
      this.scene.add(this.cubeMesh)
    },
    async loadModel(path) {
      if (!path) return;

      const loader = new OBJLoader();
      try {
        this.model = await loader.loadAsync(path)
        // 设置模型属性
        this.model.position.set(0, 0, 0)
        this.model.rotation.set(0, 0, 0)
        this.model.scale.set(0.0042, 0.0042, 0.0042)
        this.scene.add(this.model)
        this.animate()
      } catch (error) {
        console.error('模型加载失败:', error)
      }
    },

    handleMouseDown(event) {
      console.log(4444, this.hasSelection, this.disableControls)
      // if (this.hasSelection || this.disableControls) {
      //   return;
      // }

      // 标准化坐标
      const rect = this.renderer.domElement.getBoundingClientRect();
      const mouse = new THREE.Vector2(
          ((event.clientX - rect.left) / rect.width) * 2 - 1,
          -((event.clientY - rect.top) / rect.height) * 2 + 1
      );

      // 发射射线检测碰撞
      const raycaster = new THREE.Raycaster();
      raycaster.setFromCamera(mouse, this.camera);

      const intersects = raycaster.intersectObject(this.model);

      if (intersects.length > 0) {
        const uv = intersects[0].uv;
        console.log('77', uv)
        this.$emit('interact', {
          x: uv.x,
          y: 1 - uv.y,
          clientX: event.clientX,
          clientY: event.clientY,
          type: 'mousedown'
        });
      }
    },

    handleZoom(delta) {
      this.zoom = Math.max(2, Math.min(10, this.zoom + delta));
      this.camera.position.setZ(this.zoom);
    },

    animate() {
      requestAnimationFrame(this.animate);

      if (this.controls && !this.disableControls) {
        this.controls.update();
      }
      //
      // this.controls.target.set(0, 0, 0); // 确保控制器目标在原点
      // this.controls.update();

      this.renderer.render(this.scene, this.camera);
      this.centerScene()
    },

     centerScene() {
      const box = new THREE.Box3().setFromObject(this.scene);
      const center = box.getCenter(new THREE.Vector3());
      this.scene.traverse(obj => {
        if (obj.isMesh) {
          obj.position.sub(center);
        }
      });
    },

    onWindowResize() {
      console.log(664)
      this.camera.aspect = this.$refs.container.clientWidth / this.$refs.container.clientHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(
          this.$refs.container.clientWidth,
          this.$refs.container.clientHeight
      );
    },

    cleanup() {
      if (this.$refs.container && this.renderer) {
        this.$refs.container.removeChild(this.renderer.domElement);
      }
      this.renderer.domElement.removeEventListener('mousedown', this.handleMouseDown);
      window.removeEventListener('resize', this.onWindowResize);
    },

    resetCamera() {
      if (this.controls) {
        this.controls.object.position.copy(this.defaultCameraPosition.position);
        this.controls.target.copy(this.defaultCameraPosition.target);
        this.controls.update();
      }
    }
  },
  watch: {
    disableControls(newVal) {
      if (this.controls) {
        this.controls.enabled = !newVal;
        this.controls.enableRotate = !newVal;
        this.controls.enableZoom = !newVal;
        this.controls.enablePan = !newVal;
        this.controls.update();
      }
    },

    hasSelection(newVal) {
      if (this.controls) {
        this.controls.enabled = !newVal && !this.disableControls;
        this.controls.update();
      }
    },

    isScreenshotting(newVal) {
      if (newVal) {
        this.resetCamera();
      }
    },

    canvasTexture(newTexture) {
      if (this.cubeMesh && newTexture) {
        this.cubeMesh.material.map = newTexture;
        this.cubeMesh.material.needsUpdate = true;

        this.model.traverse((child) => {
          if (child instanceof Mesh) {
            child.material = this.cubeMesh.material;
          }
        });
      }
    },

    selectedModel: {
      immediate: true,

      handler(newModel) {
        this.scene && this.scene.remove(this.model) // 删除上一个衣服模型
        if (newModel) {
          this.loadModel(newModel.path);
        }
      }
    },
    model: {
      immediate: true,

      handler(newModel) {
        if (newModel) {
          this.model.traverse((child) => {
            if (child instanceof Mesh) {
              child.material = this.cubeMesh.material;
            }
          });
        }
      }
    }
  }
};
</script>

<style scoped>
.canvas-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.zoom-controls {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.5rem;
  z-index: 10;
}
</style>
